﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Server;
using System.Threading;
using System_States_Signals;

//Лэйблы по краям каждой картинки предназначениы для красивого отображения "анимации",
//чтобы знать начало координат (в последствии текст уберется)
//Визуализацию представляю так:
// - при заправке по резервуару двигается линия, которая иллюстрирует текущее состояние
// - на ТРК горит зеленая лампочка
// - если нажали кнопку заправки, а оплаты не было, на ТРК горит крассная лампочка
//Топливо качается с определенной скоростью, тоесть в резервуаре уменьшается, на ТРК показывается. 
//По истечению нужного количества кнопка блокируется, лампочка красная.
//В качестве лампочки используем PictureBox, у которого меням BackColor, по умолчанию ее цвет синий (хранить 
//предлагаю в классе ТРК константой)
namespace gas_station
{
    public partial class MainForm : Form
    {
        server _server;
        List<int> EmptyTanks = new List<int>(3);
        List<int> BadPumps = new List<int>(3);
        List<int> BadTemps = new List<int>(3);
 
        // Массив с ценами
        double[] Prices = new double[3];
        // Массив с активными RadioButton'ами
        int[] Buttons = new int[4];
        // Переменная, которая хранит номер контроллера, в котором происходит закачка
        int Cont_num = 0;
        // Какaя кнопка нажата
        KeyEventArgs PressedKey = null;
        bool Work = false;

        public MainForm()
        {
            InitializeComponent();
            _server = new server();
            _server.Init();
            lblBAK3.Text = _server.Tank_controllers[0].Data.ToString();
            lblBAK2.Text = _server.Tank_controllers[1].Data.ToString();
            lblBAK1.Text = _server.Tank_controllers[2].Data.ToString();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            foreach (var controller in _server.Tank_controllers)
            {
                controller.OnCrash += OnTankEmpty;
            }
            foreach (var controller in _server.Pump_controllers)
            {
                controller.OnCrash += OnBadPressure;
            }
            foreach (var controller in _server.Temp_controllers)
            {
                controller.OnCrash += OnBadTemperature;
            }
        }

        //private void MainForm_KeyDown(object sender, KeyEventArgs e)
        //{
        //    // Поставим нажатие на кнопку на ТРК на первые 4 цифры
        //    PressedKey = e;
        //    switch (e.KeyCode)
        //    {
        //        case Keys.D1:
        //            if (_server.TRK_controllers[0].State == Controller_State.Working)
        //            {
        //                pbxTRK1.BackColor = Color.Green;
        //                Work = true;
        //            }
        //            else
        //                pbxTRK1.BackColor = Color.Red;
        //            break;
        //        case Keys.D2:
        //            if (_server.TRK_controllers[1].State == Controller_State.Working)
        //            {
        //                pbxTRK2.BackColor = Color.Green;
        //                Work = true;
        //            }
        //            else
        //                pbxTRK2.BackColor = Color.Red;
        //            break;
        //        case Keys.D3:
        //            if (_server.TRK_controllers[2].State == Controller_State.Working)
        //            {
        //                pbxTRK3.BackColor = Color.Green;
        //                Work = true;
        //            }
        //            else
        //                pbxTRK3.BackColor = Color.Red;
        //            break;
        //        case Keys.D4:
        //            if (_server.TRK_controllers[3].State == Controller_State.Working)
        //            {
        //                pbxTRK4.BackColor = Color.Green;
        //                Work = true;
        //            }
        //            else
        //                pbxTRK4.BackColor = Color.Red; 
        //                break;
        //    }
        //}

        //private void MainForm_KeyUp(object sender, KeyEventArgs e)
        //{
        //    Work = false;
        //    PressedKey = null;
        //    switch (e.KeyCode)
        //    {
        //        case Keys.D1: pbxTRK1.BackColor = Color.Blue; break;
        //        case Keys.D2: pbxTRK2.BackColor = Color.Blue; break;
        //        case Keys.D3: pbxTRK3.BackColor = Color.Blue; break;
        //        case Keys.D4: pbxTRK4.BackColor = Color.Blue; break;
        //    }
        //}

        private void btnTRK1_Click(object sender, EventArgs e)
        {
            Cont_num = 1;
            Pay(System.Convert.ToDouble(txbTRK1Kol.Text));
        }

        private void btnTRK2_Click(object sender, EventArgs e)
        {
            Cont_num = 2;
            Pay(System.Convert.ToDouble(txbTRK2Kol.Text));
        }

        private void btnTRK3_Click(object sender, EventArgs e)
        {
            Cont_num = 3;
            Pay(System.Convert.ToDouble(txbTRK3Kol.Text));
        }

        private void btnTRK4_Click(object sender, EventArgs e)
        {
            Cont_num = 4;
            Pay(System.Convert.ToDouble(txbTRK4Kol.Text));
        }

        private void Pay(double KolFuel)
        {
            // А вот тут начинает происходить самое интересное
            // Мы активируем кнопку на ТРК
            // И теперь если нажать на кнопку топливо потечет
            // Игорь - приплети все это к нашим классам
            btnOk.Enabled = true;
            _server.TRK_controllers[Cont_num - 1].Do_Work(101);
            Fuel = KolFuel;
            FuelPart = Fuel / 20;
        }

        double Fuel = 0;
        double FuelPart = 0;
        int PartCount = 0;
        bool PrError = false;

        private void timer_Tick(object sender, EventArgs e)
        {
            if (Fuel != 0 && Work)
            {
                PartCount ++;
                _server.Pump_controllers[Buttons[Cont_num - 1]-1].Do_Work(FuelPart);
                switch(Cont_num)
                {
                    case 1:
                        txbTRK1Count.Text = (PartCount * FuelPart).ToString();
                        break;
                    case 2:
                        txbTRK2Count.Text = (PartCount * FuelPart).ToString();
                        break;
                    case 3:
                        txbTRK3Count.Text = (PartCount * FuelPart).ToString();
                        break;
                    case 4:
                        txbTRK4Count.Text = (PartCount * FuelPart).ToString();
                        break;
                }
                if (PartCount >= 20)
                {
                    _server.TRK_controllers[Cont_num - 1].Do_Work(99);
                    this.btnOk_Click(new object(),new EventArgs());
                    Fuel = 0;
                    PartCount = 0;
                    btnReset.Enabled = true;
                }
            }
            UpdateErrorLabel();
            UpdateTanks();
            // Сюда необходимо вствить условие на аварию - таймер обспечит мигание надписи
            if (PrError)
                lblError.Visible = !lblError.Visible;
        }

        private void btnChPr_Click(object sender, EventArgs e)
        {
            if (txbPrA95.Visible)
            {
                btnChPr.Text = "Установить цены";
                txbPrA95.Visible = false;
                txbPrA82.Visible = false;
                txbPrDT.Visible = false;
                Prices[0] = System.Convert.ToDouble(txbPrA95.Text);
                Prices[1] = System.Convert.ToDouble(txbPrA82.Text);
                Prices[2] = System.Convert.ToDouble(txbPrDT.Text);
                lblPRA95.Text = Prices[0].ToString();
                lblPRA82.Text = Prices[1].ToString();
                lblPRDT.Text = Prices[2].ToString();
            }
            else
            {
                btnChPr.Text = "Завершить";
                txbPrA95.Visible = true;
                txbPrA82.Visible = true;
                txbPrDT.Visible = true;
                txbPrA95.Text = Prices[0].ToString();
                txbPrA82.Text = Prices[1].ToString();
                txbPrDT.Text = Prices[2].ToString();
            }
        }

        private void ReCalc()
        {
            if (rbtnTRK1A95.Checked)
                Buttons[0] = 1;
            else
                if (rbtnTRK1A82.Checked)
                    Buttons[0] = 2;
                else
                    Buttons[0] = 3;

            if (rbtnTRK2A95.Checked)
                Buttons[1] = 1;
            else
                if (rbtnTRK2A82.Checked)
                    Buttons[1] = 2;
                else
                    Buttons[1] = 3;

            if (rbtnTRK3A95.Checked)
                Buttons[2] = 1;
            else
                if (rbtnTRK3A82.Checked)
                    Buttons[2] = 2;
                else
                    Buttons[2] = 3;

            if (rbtnTRK4A95.Checked)
                Buttons[3] = 1;
            else
                if (rbtnTRK4A82.Checked)
                    Buttons[3] = 2;
                else
                    Buttons[3] = 3;

            if (txbTRK1Kol.Text == "")
                txbTRK1Kol.Text = "0";
            txbTRK1Summ.Text = (System.Convert.ToDouble(txbTRK1Kol.Text) * Prices[Buttons[0] - 1]).ToString();

            if (txbTRK2Kol.Text == "")
                txbTRK2Kol.Text = "0";
            txbTRK2Summ.Text = (System.Convert.ToDouble(txbTRK2Kol.Text) * Prices[Buttons[1] - 1]).ToString();

            if (txbTRK3Kol.Text == "")
                txbTRK3Kol.Text = "0";
            txbTRK3Summ.Text = (System.Convert.ToDouble(txbTRK3Kol.Text) * Prices[Buttons[2] - 1]).ToString();

            if (txbTRK4Kol.Text == "")
                txbTRK4Kol.Text = "0";
            txbTRK4Summ.Text = (System.Convert.ToDouble(txbTRK4Kol.Text) * Prices[Buttons[3] - 1]).ToString(); 
        }

        #region SameThings
        private void txbTRK1Kol_Leave(object sender, EventArgs e)
        {
            ReCalc();
        }
        private void txbTRK2Kol_Leave(object sender, EventArgs e)
        {
            ReCalc();
        }
        private void txbTRK3Kol_Leave(object sender, EventArgs e)
        {
            ReCalc();
        }
        private void txbTRK4Kol_Leave(object sender, EventArgs e)
        {
            ReCalc();
        }
        private void rbtnTRK1A95_CheckedChanged(object sender, EventArgs e)
        {
            ReCalc();
        }
        private void rbtnTRK1A82_CheckedChanged(object sender, EventArgs e)
        {
            ReCalc();
        }
        private void rbtnTRK1DT_CheckedChanged(object sender, EventArgs e)
        {
            ReCalc();
        }
        private void rbtnTRK2A95_CheckedChanged(object sender, EventArgs e)
        {
            ReCalc();
        }
        private void rbtnTRK2A85_CheckedChanged(object sender, EventArgs e)
        {
            ReCalc();
        }
        private void rbtnTRK2DT_CheckedChanged(object sender, EventArgs e)
        {
            ReCalc();
        }
        private void rbtnTRK3A95_CheckedChanged(object sender, EventArgs e)
        {
            ReCalc();
        }
        private void rbtnTRK3A82_CheckedChanged(object sender, EventArgs e)
        {
            ReCalc();
        }
        private void rbtnTRK3DT_CheckedChanged(object sender, EventArgs e)
        {
            ReCalc();
        }
        private void rbtnTRK4A95_CheckedChanged(object sender, EventArgs e)
        {
            ReCalc();
        }
        private void rbtnTRK4A82_CheckedChanged(object sender, EventArgs e)
        {
            ReCalc();
        }
        private void rbtnTRK4DT_CheckedChanged(object sender, EventArgs e)
        {
            ReCalc();
        }
        #endregion

        public void UpdateTanks()
        {
            int i = 0;
            foreach (var controller in _server.Tank_controllers)
            {
                String fuel = controller.Data.ToString();
                switch (i++)
                {
                    case 0:
                        lblBAK1.Text = fuel;
                        break;
                    case 1:
                        lblBAK2.Text = fuel;
                        break;
                    case 2:
                        lblBAK3.Text = fuel;
                        break;
                    default:
                        break;
                }
            }
        }

        public void UpdateErrorLabel()
        {
            lblError.Text = "";
            if (0 != EmptyTanks.Count || 0 != BadPumps.Count || 0 != BadTemps.Count)
            {
                PrError = true;
                
                //lblError.Visible = true;
                foreach (var num in EmptyTanks)
                {
                    lblError.Text += "Tank #" + (num + 1).ToString() + " is empty\n";
                    btn_FillTanks.Enabled = true;
                }
                foreach (var num in BadPumps)
                {
                    lblError.Text += "In Pump #" + (num + 1).ToString() + " happend bad pressure\n";
                    btn_NormPressure.Enabled = true;
                }
                foreach (var num in BadTemps)
                {
                    lblError.Text += "In Tank #" + (num + 1).ToString() + " is hot\n";

                    btn_NormalTemp.Enabled = true;
                }
            }            
        }

        public void OnTankEmpty(object sender, CrashEventArgs args)
        {
            int num = 99;
            for (int i = 0; i < _server.Tank_controllers.Count; i++)
            {
                if (_server.Tank_controllers[i].Equals(sender))
                {
                    num = i;
                    EmptyTanks.Add(num);
                    break;
                }
            }
        }

        public void OnBadPressure(object sender, CrashEventArgs args)
        {
            int num = 99;
            for (int i = 0; i < _server.Pump_controllers.Count; i++)
            {
                if (_server.Pump_controllers[i].Equals(sender))
                {
                    num = i;
                    BadPumps.Add(num);
                    break;
                }
            }
        }

        public void OnBadTemperature(object sender, CrashEventArgs args)
        {
            int num = 99;
            for (int i = 0; i < _server.Temp_controllers.Count; i++)
            {
                if (_server.Temp_controllers[i].Equals(sender))
                {
                    num = i;
                    BadTemps.Add(num);
                    break;
                }
            }
        }

        private void btnOk_Click(object sender, EventArgs e)
        {
            btnOk.Enabled = false;
            switch (Cont_num)
            {
                case 1:
                    if (_server.TRK_controllers[0].State == Controller_State.Working)
                    {
                        pbxTRK1.BackColor = Color.Green;
                        Work = !Work;
                    }
                    else
                        pbxTRK1.BackColor = Color.Red;
                    break;
                case 2:
                    if (_server.TRK_controllers[1].State == Controller_State.Working)
                    {
                        pbxTRK2.BackColor = Color.Green;
                        Work = !Work;
                    }
                    else
                        pbxTRK2.BackColor = Color.Red;
                    break;
                case 3:
                    if (_server.TRK_controllers[2].State == Controller_State.Working)
                    {
                        pbxTRK3.BackColor = Color.Green;
                        Work = !Work;
                    }
                    else
                        pbxTRK3.BackColor = Color.Red;
                    break;
                case 4:
                    if (_server.TRK_controllers[3].State == Controller_State.Working)
                    {
                        pbxTRK4.BackColor = Color.Green;
                        Work = !Work;
                    }
                    else
                        pbxTRK4.BackColor = Color.Red; 
                        break;
            }
        }

        private void btnReset_Click(object sender, EventArgs e)
        {
            btnReset.Enabled = false;
            Work = false;
            Fuel = 0;
            FuelPart = 0;
            PartCount = 0;
            txbTRK1Count.Text = "";
            txbTRK2Count.Text = "";
            txbTRK3Count.Text = "";
            txbTRK4Count.Text = "";
            pbxTRK1.BackColor = Color.Blue;
            pbxTRK2.BackColor = Color.Blue;
            pbxTRK3.BackColor = Color.Blue;
            pbxTRK4.BackColor = Color.Blue;
        }

        private void btnCrash_Click(object sender, EventArgs e)
        {
            _server.Pump_controllers[1].Do_Crash();
        }

        private void btn_RaiseTemp_Click(object sender, EventArgs e)
        {
            _server.Temp_controllers[2].Do_Crash();
        }

        private void btn_FillTanks_Click(object sender, EventArgs e)
        {
            if (0 != EmptyTanks.Count)
            {
                foreach (var num in EmptyTanks)
                {
                    _server.Tanks[num].Refill();
                    _server.Tank_controllers[num].StartChecking();
                }
                EmptyTanks.Clear();
                // что-то сделать с lblError
                if (0 == BadPumps.Count && 0 == BadTemps.Count)
                {
                    lblError.Visible = false;
                }
                btn_FillTanks.Enabled = false;
            }
        }

        private void btn_NormPressure_Click(object sender, EventArgs e)
        {
            if (0 != BadPumps.Count)
            {
                foreach (var num in BadPumps)
                {
                    _server.Tanks[num].Repair_Pressure();
                    _server.Pump_controllers[num].StartChecking();
                }
                BadPumps.Clear();
                // что-то сделать с lblError
                if (0 == EmptyTanks.Count && 0 == BadTemps.Count)
                {
                    lblError.Visible = false;
                }
                btn_NormPressure.Enabled = false;
            }
        }

        private void btn_NormalTemp_Click(object sender, EventArgs e)
        {
            if (0 != BadTemps.Count)
            {
                foreach (var num in BadTemps)
                {
                    _server.Tanks[num].Repair_Temperature();
                    _server.Temp_controllers[num].StartChecking();
                }
                BadTemps.Clear();
                // что-то сделать с lblError
                if (0 == EmptyTanks.Count && 0 == BadPumps.Count)
                {
                    lblError.Visible = false;
                }
                btn_NormalTemp.Enabled = false;
            }
        }
    }
}
